import { Fragment, useCallback, useState, type ReactElement } from 'react'
import { Dialog, Transition } from '@headlessui/react'

type Options = {
  title: string
  description?: string
  confirmText?: string
  cancelText?: string
}

type InternalState = Options & { resolve: (result: boolean) => void }

export const useConfirmDialog = (): [
  (options: Options) => Promise<boolean>,
  () => ReactElement | null,
] => {
  const [state, setState] = useState<InternalState | null>(null)

  const open = useCallback((options: Options) => {
    return new Promise<boolean>((resolve) => {
      setState({ ...options, resolve })
    })
  }, [])

  const handleClose = useCallback(
    (result: boolean) => {
      if (state) {
        state.resolve(result)
        setState(null)
      }
    },
    [state],
  )

  const DialogRenderer = useCallback(() => {
    if (!state) return null
    return (
      <Transition.Root show as={Fragment}>
        <Dialog as="div" className="relative z-[1000]" onClose={() => handleClose(false)}>
          <Transition.Child
            as={Fragment}
            enter="duration-150 ease-out"
            enterFrom="opacity-0"
            enterTo="opacity-100"
            leave="duration-100 ease-in"
            leaveFrom="opacity-100"
            leaveTo="opacity-0"
          >
            <div className="fixed inset-0 bg-slate-900/30 backdrop-blur-sm" />
          </Transition.Child>

          <div className="fixed inset-0 flex items-center justify-center px-4">
            <Transition.Child
              as={Fragment}
              enter="duration-150 ease-out"
              enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
              enterTo="opacity-100 translate-y-0 sm:scale-100"
              leave="duration-100 ease-in"
              leaveFrom="opacity-100 translate-y-0 sm:scale-100"
              leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
            >
              <Dialog.Panel className="w-full max-w-sm rounded-2xl bg-white p-5 shadow-xl">
                <Dialog.Title className="text-base font-semibold text-slate-900">{state.title}</Dialog.Title>
                {state.description ? (
                  <p className="mt-2 text-sm text-slate-500">{state.description}</p>
                ) : null}
                <div className="mt-5 flex justify-end gap-2">
                  <button
                    type="button"
                    className="rounded-full border border-slate-200 px-4 py-2 text-xs font-semibold text-slate-500"
                    onClick={() => handleClose(false)}
                  >
                    {state.cancelText ?? '取消'}
                  </button>
                  <button
                    type="button"
                    className="rounded-full bg-red-500 px-4 py-2 text-xs font-semibold text-white shadow-sm"
                    onClick={() => handleClose(true)}
                  >
                    {state.confirmText ?? '确认'}
                  </button>
                </div>
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </Dialog>
      </Transition.Root>
    )
  }, [handleClose, state])

  return [open, DialogRenderer]
}

export default useConfirmDialog
